package com.ctshk.rpc.hotel.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.NumberUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.hotel.dto.*;
import com.ctshk.rpc.hotel.dto.booking.HotelProductUnitPriceDTO;
import com.ctshk.rpc.hotel.dto.h5.HotelRoomDTO;
import com.ctshk.rpc.hotel.entity.*;
import com.ctshk.rpc.hotel.mapper.*;
import com.ctshk.rpc.hotel.req.*;
import com.ctshk.rpc.hotel.req.booking.HotelProductUnitPriceReq;
import com.ctshk.rpc.hotel.req.h5.RoomDetailsQueryH5Req;
import com.ctshk.rpc.hotel.service.IHotelH5Service;
import com.ctshk.rpc.hotel.service.IHotelProductService;
import com.ctshk.rpc.system.dto.MainDataCurrencyQueryDTO;
import com.ctshk.rpc.system.dto.SysDepartmentDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.req.MainDataCurrencyUpdateStatusReq;
import com.ctshk.rpc.system.service.IMainDataCurrencyService;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import com.github.houbb.heaven.util.util.CollectionUtil;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 酒店产品 服务实现类
 * </p>
 *
 * @author yinhuan
 * @since 2021-03-03
 */
@Slf4j
@DubboService
public class HotelProductServiceImpl extends ServiceImpl<HotelProductMapper, HotelProduct> implements IHotelProductService {
    @Autowired
    private HotelProductMapper hotelProductMapper;
    @Autowired
    private HotelProductCostMapper hotelProductCostMapper;
    @Autowired
    private HotelProductCostDateMapper hotelProductCostDateMapper;
    @Autowired
    private HotelProductStrategyMapper hotelProductStrategyMapper;
    @Autowired
    private HotelProductIncreaseStrategyRuleMapper ruleMapper;
    @Autowired
    private HotelProductChannelOfflineAgentCustomMapper hotelProductChannelOfflineAgentCustomMapper;
    @Autowired
    private HotelInitializationSettingsMapper hotelInitializationSettingsMapper;
    @Autowired
    private HotelInitializationSettingsChannelMapper hotelInitializationSettingsChannelMapper;
    @Autowired
    private HotelProductChannelOfflineSelfCustomMapper hotelProductChannelOfflineSelfCustomMapper;
    @Autowired
    private HotelMapper hotelMapper;
    @Autowired
    private HotelProductIncreaseStrategyRuleMapper hotelProductIncreaseStrategyRuleMapper;
    @Autowired
    private HotelFacilitiesMapper hotelFacilitiesMapper;
    @Autowired
    private HotelRoomTypeMapper hotelRoomTypeMapper;
    @Autowired
    private IHotelH5Service hotelH5Service;

    @DubboReference
    private ISysDepartmentService sysDepartmentService;
    @DubboReference
    private ISysUserService sysUserService;
    @DubboReference
    private ISysApprovalService sysApprovalService;
    @DubboReference
    private IMainDataCurrencyService mainDataCurrencyService;
    @DubboReference
    private ISysPermissionService sysPermissionService;
    /**
     * 1-推荐
     */
    public final static Integer RECOMMENDED = 1;
    public final static Integer UN_RECOMMENDED = 0;

    public final static Integer SALE_CHANNEL_TYPE_DISABLED = 1; //销售渠道类型：禁售
    public final static Integer SALE_CHANNEL_TYPE_ALL = 2; //销售渠道类型：所有
    public final static Integer SALE_CHANNEL_TYPE_SELECTED = 3; //销售渠道类型：选中的
    public final static Integer SALE_TYPE_UNLIMITED = 1; // 销售数量类型：无限制
    public final static Integer SALE_TYPE_LIMIT = 2; // 销售数量类型：有限制

    /**  0-未删除  1-已删除*/
    public final static Integer NOT_DELETE = 0;
    public final static Integer IS_DELETED = 1;

    /**  1-有效  2-无效*/
    public final static Integer VALID = 1;
    public final static Integer INVALID  = 2;

    /**
     * 酒店产品管理列表
     * */
    @Override
    public PageResponse<HotelProductListDTO> queryList(HotelListProductReq req, long userId) {
        /* todo 前端未传menuId,待前端加上后放开注释
        Result<List<Long>> permissionResult = sysPermissionService.queryPermission(req.getMenuId(), userId);
        if (!permissionResult.isSuccess()) {
            SystemError result = SystemError.getDefined(permissionResult.getCode());
            throw new BusinessException(result);
        }*/
        Page<HotelProductListDTO> page = new Page<>(req.getPageNo(), req.getPageSize());
        Page<HotelProductListDTO> iPage = hotelProductMapper.queryHotelProductList(req,page);
        List<HotelProductListDTO> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        return new PageResponse<>(records, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }



    /**
     * 酒店预订查询
     * */
    @Override
    public PageResponse<RecommendedHotelDTO> queryReservetionList(HotelReservertionReq req) {
        Page<RecommendedHotelDTO> page = new Page<>(req.getPageNo(), req.getPageSize());
        Page<RecommendedHotelDTO> iPage = hotelProductMapper.queryAllRecommendedHotel(req,page);
        List<RecommendedHotelDTO> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        return new PageResponse<>(records, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }



    //根据酒店品牌查询酒店
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HotelNameInfoDTO> getHotelInfoByBrand(HotelNameAndIdReq hotelNameAndIdReq) {
        List<HotelNameInfoDTO> hotelNameInfoDTOList = new ArrayList<HotelNameInfoDTO>();
        QueryWrapper<Hotel> queryWrapper  = new QueryWrapper<>();
        queryWrapper.lambda().eq(Hotel::getBrandId,hotelNameAndIdReq.getId());
        queryWrapper.lambda().eq(Hotel::getIsDeleted,IsDeletedCode.NO.getCode());
        List<Hotel> hotels = hotelMapper.selectList(queryWrapper);
        if(CollectionUtils.isNotEmpty(hotels)){
            for (int i = 0; i < hotels.size(); i++) {
                Hotel hotel = hotels.get(i);
                HotelNameInfoDTO hotelNameInfoDTO = new HotelNameInfoDTO();
                hotelNameInfoDTO.setId(hotel.getId());
                hotelNameInfoDTO.setName(hotel.getName());
                hotelNameInfoDTOList.add(hotelNameInfoDTO);
            }
        }
        return hotelNameInfoDTOList;
    }

    //根据酒店ID查询酒店房型
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HotelNameInfoDTO> getHotelRoomNameInfo(HotelNameAndIdReq hotelNameAndIdReq) {
        List<HotelNameInfoDTO> hotelNameInfoDTOList = new ArrayList<HotelNameInfoDTO>();
        QueryWrapper<HotelRoomType> queryWrapper  = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelRoomType::getHotelId,hotelNameAndIdReq.getId());
        queryWrapper.lambda().eq(HotelRoomType::getIsDeleted,IsDeletedCode.NO.getCode());
        List<HotelRoomType> hotelRoomTypes = hotelRoomTypeMapper.selectList(queryWrapper);
        if(CollectionUtils.isNotEmpty(hotelRoomTypes)){
            for (int i = 0; i < hotelRoomTypes.size(); i++) {
                HotelRoomType hotelRoomType = hotelRoomTypes.get(i);
                HotelNameInfoDTO hotelNameInfoDTO = new HotelNameInfoDTO();
                hotelNameInfoDTO.setId(hotelRoomType.getId());
                hotelNameInfoDTO.setName(hotelRoomType.getName());
                hotelNameInfoDTOList.add(hotelNameInfoDTO);
            }
        }
        return hotelNameInfoDTOList;
    }

    /**
     * 根据币种ID获取汇率，获取汇率,
     *
     * @return
     */
    private MainDataCurrencyQueryDTO getExchangeRateByName(Long currencyId) {
        MainDataCurrencyUpdateStatusReq mainDataCurrencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
        mainDataCurrencyUpdateStatusReq.setId(currencyId);
        Result<MainDataCurrencyQueryDTO> queryCurrencyRateResult = mainDataCurrencyService.query(mainDataCurrencyUpdateStatusReq);
        log.info("【查询汇率】exchange rate:{}", JSON.toJSONString(queryCurrencyRateResult));
        if (!queryCurrencyRateResult.isSuccess()) {
            SystemError defined = SystemError.getDefined(queryCurrencyRateResult.getCode());
            throw new BusinessException(defined);
        }
        return queryCurrencyRateResult.getData();
    }

    //保存新增产品
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveHotelProduct(HotelProductDataReq hotelProductDataReq, TokenUser user) {
        if (hotelProductDataReq.getRoomId() == null) {
            return Result.failed(SystemError.HOTEL_10090);
        }
        //去重，供应商+房型+早餐
        QueryWrapper<HotelProduct> queryWrapper  = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProduct::getRoomId,hotelProductDataReq.getRoomId());
        queryWrapper.lambda().eq(HotelProduct::getSupplierId,hotelProductDataReq.getSupplierId());
        queryWrapper.lambda().eq(HotelProduct::getHasBreakfast,hotelProductDataReq.getHasBreakfast());
        queryWrapper.lambda().eq(HotelProduct::getIsDeleted,0);
        Integer count = hotelProductMapper.selectCount(queryWrapper);
        if(count != 0){
            return  Result.failed(SystemError.HOTEL_10040);
        }
        /**判断成本日期是否存在重合 因为最后以后包含在时间范围内 获取时 结束日期加1天*/
        List<HotelProductCostAddReq> hotelProductCostDataReqList = hotelProductDataReq.getHotelProductCostDataReqs();
        /**localDateSet 去除重复日期 localDateSize未去除重复日期时的日期总笔 如果两者不相等 则存在重复日期*/
        Set<LocalDate> localDateSet = Sets.newHashSet();
        int localDateSize = 0;
        if(CollectionUtils.isNotEmpty(hotelProductCostDataReqList)){
            for (HotelProductCostAddReq hotelProductCostDataReq : hotelProductCostDataReqList) {
                List<HotelProductCostDateData> hotelProductCostDateDataList = hotelProductCostDataReq.getHotelProductCostDateReqList();
                for (HotelProductCostDateData hotelProductCostDateData : hotelProductCostDateDataList) {
                    LocalDate dateBegin = hotelProductCostDateData.getDateBegin();
                    LocalDate dateEnd = hotelProductCostDateData.getDateEnd();
                    List<LocalDate> dates = Stream.iterate(dateBegin, date -> date.plusDays(1))
                            .limit(ChronoUnit.DAYS.between(dateBegin, dateEnd))
                            .collect(Collectors.toList());
                    localDateSet.addAll(dates);
                    localDateSize+=dates.size();
                }
            }
        }
        if(localDateSet.size() != localDateSize){
            return  Result.failed(SystemError.HOTEL_10045);
        }
        /**酒店产品主体信息*/
        HotelProduct hotelProduct = EntityUtil.copy(hotelProductDataReq,HotelProduct.class);//产品主体信息
        hotelProduct.setSaleStatus(0);
        hotelProduct.setIsRecommend(0);
        hotelProduct.setCreateId(user.getId());
        hotelProduct.setGmtCreate(LocalDateTime.now());
        hotelProduct.setModifiedId(user.getId());
        hotelProduct.setGmtModified(LocalDateTime.now());
//        hotelProduct.setSourceType(NumberConstant.ONE.getValue());
        hotelProduct.setProductCode("HOTEL_"+LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"))+"_"+ LocalTime.now().format(DateTimeFormatter.ofPattern("HHmmss")));
        Long hotelProductId = IdWorker.getId();
        hotelProduct.setId(hotelProductId);
        hotelProduct.setIsDeleted(IsDeletedCode.NO.getCode());
        hotelProduct.setHotelId(hotelProductDataReq.getHotelId());
        hotelProduct.setSourceType(ProductType.MANUAL_ENTRY.getCode());
        hotelProduct.setRoomId(hotelProductDataReq.getRoomId());
        hotelProduct.setApprovalStatus(ApproveCode.UN_COMMIT.getCode());
        hotelProduct.setOnShelfStatus(SaleOnShelfStatusCode.ON_SHELF_STATUS_0.getCode());
        hotelProduct.setProductNumber(NumberUtil.generatorHotelProductNumber(user.getEmployeeNumber()));
        baseMapper.insert(hotelProduct);

        /**成本信息*/
        if(CollectionUtils.isNotEmpty(hotelProductCostDataReqList)){
            for (HotelProductCostAddReq hotelProductCostDataReq : hotelProductCostDataReqList) {
                /**成本主体*/
                HotelProductCost hotelProductCost = EntityUtil.copy(hotelProductCostDataReq, HotelProductCost.class);
                hotelProductCost.setHotelProductId(hotelProductId);
                Long hotelProductCostId = IdWorker.getId();
                hotelProductCost.setId(hotelProductCostId);
                // hotelProductCost.setExchangeRate(getExchangeRateByName(hotelProductCost.getCurrencyId()).getPlannedExchangeRate());
                hotelProductCost.setPrice(new BigDecimal(hotelProductCostDataReq.getPrice()));
                /**成本日期*/
                if(CollectionUtils.isNotEmpty(hotelProductCostDataReq.getHotelProductCostDateReqList())) {
                    List<HotelProductCostDateData> hotelProductCostDateDataList = hotelProductCostDataReq.getHotelProductCostDateReqList();
                    for (HotelProductCostDateData hotelProductCostDateData : hotelProductCostDateDataList) {
                        HotelProductCostDate hotelProductCostDate = EntityUtil.copy(hotelProductCostDateData, HotelProductCostDate.class);
                        hotelProductCostDate.setCostId(hotelProductCostId);
                        Long hotelProductCostDateId = IdWorker.getId();
                        hotelProductCostDate.setId(hotelProductCostDateId);
                        hotelProductCostDate.setDateBegin(hotelProductCostDateData.getDateBegin());
                        hotelProductCostDateMapper.insert(hotelProductCostDate);
                    }
                }
                hotelProductCostMapper.insert(hotelProductCost);
            }
        }
        return Result.success(hotelProductId);
    }

    //返回上一步时，修改产品
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateHotelProduct(HotelProductDataReq hotelProductDataReq, TokenUser user) {
        if (hotelProductDataReq.getRoomId() == null) {
            return Result.failed(SystemError.HOTEL_10090);
        }
        if(hotelProductDataReq.getId()==null){
            return Result.failed(SystemError.HOTEL_10049);
        }else{
            if(hotelProductDataReq.getId()==null||hotelProductDataReq.equals("")){
                //去重，供应商+房型+早餐  修改的时候就不判断这一步
                QueryWrapper<HotelProduct> queryWrapper  = new QueryWrapper<>();
                queryWrapper.lambda().eq(HotelProduct::getRoomId,hotelProductDataReq.getRoomId());
                queryWrapper.lambda().eq(HotelProduct::getSupplierId,hotelProductDataReq.getSupplierId());
                queryWrapper.lambda().eq(HotelProduct::getHasBreakfast,hotelProductDataReq.getHasBreakfast());
                queryWrapper.lambda().eq(HotelProduct::getIsDeleted,0);
                Integer count = hotelProductMapper.selectCount(queryWrapper);
                if(count != 0){
                    return  Result.failed(SystemError.HOTEL_10040);
                }
            }
            HotelProduct hotelProduct = hotelProductMapper.selectById(hotelProductDataReq.getId());
            if(hotelProduct==null){
                return Result.failed(SystemError.HOTEL_10040);
            }else{
                //更新酒店产品主体
                HotelProduct hotelProductObj = EntityUtil.copy(hotelProductDataReq, HotelProduct.class);
                hotelProductObj.setId(hotelProductDataReq.getId());
                hotelProductObj.setModifiedId(user.getId());
                hotelProductObj.setGmtModified(LocalDateTime.now());
                hotelProductMapper.updateById(hotelProductObj);

                //删除酒店成本和酒店成本日期，根据hotelProductId
                QueryWrapper<HotelProductCost> queryWrapperCost  = new QueryWrapper<>();
                queryWrapperCost.lambda().eq(HotelProductCost::getHotelProductId,hotelProductDataReq.getId());
                List<HotelProductCost> hotelProductCostList = hotelProductCostMapper.selectList(queryWrapperCost);
                if(CollectionUtils.isNotEmpty(hotelProductCostList)){
                    for (int i = 0; i <hotelProductCostList.size() ; i++) {
                        HotelProductCost hotelProductCost = hotelProductCostList.get(i);
                        hotelProductCostMapper.deleteById(hotelProductCost.getId());
                        //删除成本日期
                        QueryWrapper<HotelProductCostDate> queryWrapperCostDate  = new QueryWrapper<>();
                        queryWrapperCostDate.lambda().eq(HotelProductCostDate::getCostId,hotelProductCost.getId());
                        List<HotelProductCostDate> hotelProductCostDateList = hotelProductCostDateMapper.selectList(queryWrapperCostDate);
                        if(CollectionUtils.isNotEmpty(hotelProductCostDateList)){
                            for (int i1 = 0; i1 < hotelProductCostDateList.size(); i1++) {
                                HotelProductCostDate hotelProductCostDate = hotelProductCostDateList.get(i1);
                                hotelProductCostDateMapper.deleteById(hotelProductCostDate.getId());
                            }
                        }
                    }
                }
                //新增酒店成本和酒店成本日期
                if(CollectionUtils.isNotEmpty(hotelProductDataReq.getHotelProductCostDataReqs())){
                    for (int i = 0; i <hotelProductDataReq.getHotelProductCostDataReqs().size() ; i++) {
                        //保存成本主体
                        HotelProductCostAddReq hotelProductCostAddReq = hotelProductDataReq.getHotelProductCostDataReqs().get(i);
                        if (null == hotelProductCostAddReq.getCurrencyId() || null == hotelProductCostAddReq.getExchangeRate()) {
                            return Result.failed(SystemError.HOTEL_10079);
                        }
                        HotelProductCost hotelProductCost = EntityUtil.copy(hotelProductCostAddReq, HotelProductCost.class);
                        hotelProductCost.setId(IdWorker.getId());
                        hotelProductCost.setPrice(new BigDecimal(hotelProductCostAddReq.getPrice()));
                        hotelProductCost.setHotelProductId(hotelProductDataReq.getId());
                        hotelProductCostMapper.insert(hotelProductCost);
                        //保存酒店成本日期主体
                        if(CollectionUtils.isNotEmpty(hotelProductCostAddReq.getHotelProductCostDateReqList())){
                            List<HotelProductCostDateData> hotelProductCostDateReqList = hotelProductCostAddReq.getHotelProductCostDateReqList();
                            for (int j = 0; j <hotelProductCostDateReqList.size() ; j++) {
                                HotelProductCostDateData hotelProductCostDateData = hotelProductCostDateReqList.get(j);
                                HotelProductCostDate hotelProductCostDate = EntityUtil.copy(hotelProductCostDateData, HotelProductCostDate.class);
                                hotelProductCostDate.setCostId(hotelProductCost.getId());
                                hotelProductCostDate.setId(IdWorker.getId());
                                hotelProductCostDateMapper.insert(hotelProductCostDate);
                            }
                        }
                    }
                }
            }
        }

        /**
         * 清除C端缓存
         */
        ThreadUtil.execAsync(() -> {
            hotelH5Service.cacheUpdate(hotelProductDataReq.getHotelId());
        });

        return  Result.success();
    }


    /**
     * 修改酒店产品预订信息
     * @param hotelProductDataReq
     * @param user
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result updateReservation(HotelProductDataReq hotelProductDataReq, TokenUser user) {
        if (hotelProductDataReq.getSubmitStatus() == null) {
            BusinessException businessException = new BusinessException(SystemError.SYS_409, "submitStatus");
            return Result.failed(businessException);
        }
        if (hotelProductDataReq.getReserveChargeType() == null) {
            return Result.failed(SystemError.HOTEL_10091);
        }
        if (hotelProductDataReq.getReserveCharge() == null) {
            return Result.failed(SystemError.HOTEL_10092);
        }
        if (hotelProductDataReq.getRefundChargeType() == null) {
            return Result.failed(SystemError.HOTEL_10093);
        }
        if (hotelProductDataReq.getRefundCharge() == null) {
            return Result.failed(SystemError.HOTEL_10094);
        }
        if (hotelProductDataReq.getTaxation() == null) {
            return Result.failed(SystemError.HOTEL_10095);
        }
        if (hotelProductDataReq.getIsSecCheck() == null) {
            return Result.failed(SystemError.HOTEL_10097);
        }
        if (hotelProductDataReq.getIsSecCheck() == null) {
            return Result.failed(SystemError.HOTEL_10098);
        }

        QueryWrapper<HotelProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProduct::getId,hotelProductDataReq.getId());
        queryWrapper.lambda().eq(HotelProduct::getIsDeleted,IsDeletedCode.NO.getCode());
        HotelProduct hotelProduct = hotelProductMapper.selectOne(queryWrapper);
        if(hotelProduct != null) {
            hotelProduct.setSaleTimeType(hotelProductDataReq.getSaleTimeType());
            hotelProduct.setAllowRefund(hotelProductDataReq.getAllowRefund());
            //hotelProduct.setCheckNow(hotelProductReservationSettingsDataReq.getCheckNow());
            hotelProduct.setCustomerNotice(hotelProductDataReq.getCustomerNotice());
            hotelProduct.setIsSecCheck(hotelProductDataReq.getIsSecCheck());
            hotelProduct.setRefundCharge(hotelProductDataReq.getRefundCharge());
            hotelProduct.setRefundChargeType(hotelProductDataReq.getRefundChargeType());
//            hotelProduct.setReservationComfrim(hotelProductReservationSettingsDataReq.getReservationComfrim());
            hotelProduct.setReserveCharge(hotelProductDataReq.getReserveCharge());
            hotelProduct.setSaleBegin(hotelProductDataReq.getSaleBegin());
            hotelProduct.setSaleEnd(hotelProductDataReq.getSaleEnd());
            hotelProduct.setSaleTimeType(hotelProductDataReq.getSaleTimeType());
            hotelProduct.setTaxation(hotelProductDataReq.getTaxation());

            if (hotelProductDataReq.getSubmitStatus() == 2) {
                // 保存并发起审批
                Result<ApprovalStartDTO> startDTOResult = sysApprovalService.start(SystemBusinessType.HOTEL.getCode(), SysApprovalType.ADD_HOTEL.getCode(), hotelProduct.getId(), user.getId(), null, null);
                if (!startDTOResult.isSuccess()) {
                    SystemError systemError = SystemError.getDefined(startDTOResult.getCode());
                    throw new BusinessException(systemError);
                }
                hotelProduct.setApprovalStatus(ApprovalStatus.REVIEWING.getCode());
            }
            hotelProductMapper.updateById(hotelProduct);
        } else {
            throw new BusinessException(SystemError.HOTEL_10014);
        }

        /**
         * 清除C端缓存
         */
        ThreadUtil.execAsync(() -> {
            hotelH5Service.cacheUpdate(hotelProductDataReq.getHotelId());
        });

        return Result.success();
    }

    @Override
    public Result setValid(Long id, TokenUser tokenUser) {
        QueryWrapper<HotelProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProduct::getId,id);
        HotelProduct hotelProduct = baseMapper.selectOne(queryWrapper);
        if(hotelProduct.getSaleStatus() == 1){
            hotelProduct.setSaleStatus(0);
        } else {
            hotelProduct.setSaleStatus(1);
        }
        hotelProduct.setGmtModified(LocalDateTime.now());
        hotelProduct.setModifiedId(tokenUser.getId());
        baseMapper.updateById(hotelProduct);
        return Result.success(id);
    }

    /**
     * 产品预订信息
     * @param hotelProductReq
     * @return
     */
    @Override
    public Result saveHotelResevertionProduct(HotelProductReq hotelProductReq, TokenUser user) {
        if(hotelProductReq==null){
            return Result.failed(SystemError.HOTEL_10046);
        }
        if(hotelProductReq.getId().equals("")||hotelProductReq.getId()==null){
            return Result.failed(SystemError.HOTEL_10047);
        }
        QueryWrapper<HotelProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProduct::getId,hotelProductReq.getId());
        queryWrapper.lambda().eq(HotelProduct::getIsDeleted,IsDeletedCode.NO.getCode());
        HotelProduct hotelProduct = hotelProductMapper.selectOne(queryWrapper);
        //保存产品预订信息
        if(hotelProduct!=null){
            hotelProduct.setSaleTimeType(hotelProductReq.getSaleTimeType());
            hotelProduct.setAllowRefund(hotelProductReq.getAllowRefund());
            //hotelProduct.setCheckNow(hotelProductReservationSettingsDataReq.getCheckNow());
            hotelProduct.setCustomerNotice(hotelProductReq.getCustomerNotice());
            hotelProduct.setId(hotelProductReq.getId());
            hotelProduct.setIsSecCheck(hotelProductReq.getIsSecCheck());
            hotelProduct.setRefundCharge(hotelProductReq.getRefundCharge());
            hotelProduct.setRefundChargeType(hotelProductReq.getRefundChargeType());
//            hotelProduct.setReservationComfrim(hotelProductReservationSettingsDataReq.getReservationComfrim());
            hotelProduct.setReserveCharge(hotelProductReq.getReserveCharge());
            hotelProduct.setSaleBegin(hotelProductReq.getSaleBegin());//前端传String,转换为LocalDateTime
            hotelProduct.setSaleEnd(hotelProductReq.getSaleEnd());//前端传String,转换为LocalDateTime
            hotelProduct.setSaleTimeType(hotelProductReq.getSaleTimeType());
            hotelProduct.setTaxation(hotelProductReq.getTaxation());
            hotelProductMapper.updateById(hotelProduct);
        }else{
            return Result.failed(SystemError.HOTEL_10048);
        }
        return Result.success();
    }

    @Override
    public HotelProductDTO queryDetail(Long id) {
        QueryWrapper<HotelProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProduct::getId,id);
        HotelProduct hotelProduct = baseMapper.selectOne(queryWrapper);
        HotelProductDTO hotelProductDTO = EntityUtil.copy(hotelProduct, HotelProductDTO.class);
        if(null != hotelProductDTO){
            //根据product表的hotelId查询酒店名称和品牌
            QueryWrapper<HotelProductCost> hotelProductCostQueryWrapper = new QueryWrapper<>();
            hotelProductCostQueryWrapper.lambda().eq(HotelProductCost::getHotelProductId,hotelProduct.getId());
            List<HotelProductCost> hotelProductCosts = hotelProductCostMapper.selectList(hotelProductCostQueryWrapper);

            QueryWrapper<Hotel> hotelQueryWrapper = new QueryWrapper<>();
            hotelQueryWrapper.lambda().eq(Hotel::getId,hotelProduct.getHotelId());
            Hotel hotel = hotelMapper.selectOne(hotelQueryWrapper);
            if(hotel!=null){
                hotelProductDTO.setHotelName(hotel.getName());
                hotelProductDTO.setBrandName(hotel.getBrandName());
                List<HotelProductCostDTO> hotelProductCostDTOS = EntityUtil.copyList(hotelProductCosts, HotelProductCostDTO.class);
                if(CollectionUtils.isNotEmpty(hotelProductCostDTOS)){
                    for (HotelProductCostDTO hotelProductCostDTO:hotelProductCostDTOS ) {
                        QueryWrapper<HotelProductCostDate> hotelProductCostDateQueryWrapper = new QueryWrapper<>();
                        hotelProductCostDateQueryWrapper.lambda().eq(HotelProductCostDate::getCostId,hotelProductCostDTO.getId());
                        List<HotelProductCostDate> hotelProductCostDates = hotelProductCostDateMapper.selectList(hotelProductCostDateQueryWrapper);
                        List<HotelProductCostDateData> hotelProductCostDateDataList = EntityUtil.copyList(hotelProductCostDates, HotelProductCostDateData.class);
                        hotelProductCostDTO.setHotelProductCostDateDTO(hotelProductCostDateDataList);
                    }
                    hotelProductDTO.setHotelProductCostDtoList(hotelProductCostDTOS);
                }
            }
        }
        return hotelProductDTO;
    }

    /**
     * 批量设置
     * @param batchHotelProductInfoReq
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result batchSettingHotel(BatchHotelProductInfoReq batchHotelProductInfoReq, TokenUser user) {
        if(Objects.isNull(user)){
            return Result.failed(SystemError.USER_1000);
        }
        if(Objects.isNull(batchHotelProductInfoReq)
                || org.springframework.util.CollectionUtils.isEmpty(batchHotelProductInfoReq.getHotelProductIds())){
            return Result.failed(SystemError.HOTEL_10052);
        }
        List<HotelProduct> hotelProductList = hotelProductMapper.selectList(new QueryWrapper<HotelProduct>().lambda().in(HotelProduct::getId, batchHotelProductInfoReq.getHotelProductIds()));

        //判断产品来源是否相同
        if(!org.springframework.util.CollectionUtils.isEmpty(hotelProductList)){
            for(HotelProduct hotelProduct : hotelProductList){
                if(!hotelProductList.get(0).getSourceType().equals(hotelProduct.getSourceType())){
                    return Result.failed(SystemError.HOTEL_10062);
                }
                if(ProductType.MANUAL_ENTRY.getCode() == hotelProduct.getSourceType() &&
                        !ApproveCode.APPROVE_PASS.getCode().equals(hotelProduct.getApprovalStatus())){
                    return Result.failed(SystemError.TRAIN_PRODUCT_14012);
                }
            }
            for(HotelProduct hotelProduct: hotelProductList){
                hotelProduct.setAllowPackage(batchHotelProductInfoReq.getAllowPackage());
                hotelProduct.setSaleStatus(batchHotelProductInfoReq.getSaleStatus());
                hotelProduct.setChargeId(batchHotelProductInfoReq.getChargeId());
                hotelProduct.setModifiedId(user.getId());
                hotelProduct.setGmtModified(LocalDateTime.now());
                hotelProductMapper.updateById(hotelProduct);
            }
        }

        return Result.success();
    }

    /**
     * api设置
     * @param hotelProductSetReq
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result setApi(HotelProductSetReq hotelProductSetReq, TokenUser user) {
        HotelProduct hotelProduct = hotelProductMapper.selectById(hotelProductSetReq.getProductId());
        if(Objects.isNull(hotelProduct)){
            return Result.failed(SystemError.HOTEL_10038);
        }
        //是API产品才可以设置
        if(ProductType.API_PRODUCT.getCode() == hotelProduct.getSourceType()){
            hotelProduct.setAllowPackage(hotelProductSetReq.getAllowPackage());
            hotelProduct.setChargeId(hotelProductSetReq.getChargeId());
            hotelProduct.setReserveCharge(hotelProductSetReq.getRefundCharge());
            hotelProduct.setRefundChargeType(hotelProductSetReq.getRefundChargeType());
            hotelProduct.setReserveCharge(hotelProductSetReq.getReserveCharge());
            hotelProduct.setReserveChargeType(hotelProductSetReq.getReserveChargeType());
            hotelProduct.setModifiedId(user.getId());
            hotelProduct.setGmtModified(LocalDateTime.now());
            hotelProductMapper.updateById(hotelProduct);
        }else{
            return Result.failed(SystemError.HOTEL_10063);
        }
        return Result.success();
    }

    /**
     * 推荐设置
     * @param hotelRecommendedReq
     */
    @Override
    public Result setRecommended(HotelRecommendedReq hotelRecommendedReq, TokenUser user) {
        if(hotelRecommendedReq.getProductId()!=null){
            HotelProduct hotelProduct = hotelProductMapper.selectById(hotelRecommendedReq.getProductId());
            if(Objects.isNull(hotelProduct)){
                return Result.failed(SystemError.HOTEL_10049);
            }
            if(RECOMMENDED.equals(hotelProduct.getIsRecommend())){
                hotelProduct.setIsRecommend(UN_RECOMMENDED); //设置为不推荐
            }else{
                hotelProduct.setIsRecommend(RECOMMENDED); //设置为推荐
            }
            hotelProduct.setModifiedId(user.getId());
            hotelProduct.setRecommendTime(LocalDateTime.now());
            hotelProduct.setGmtModified(LocalDateTime.now());
            hotelProductMapper.updateById(hotelProduct);
            return Result.success(hotelProduct.getId());
        }else{
            return Result.failed(SystemError.HOTEL_10065);
        }

    }


    /**
     * 查询酒店推荐列表
     */
    @Override
    public List<RecommendedHotelDTO> queryRecommendedHotel(Long userId) {
        LocalDate nowDate = LocalDate.now();
        List<RecommendedHotelDTO> recommendedHotelDTOList = hotelProductMapper.queryRecommendedHotel();
        if(org.springframework.util.CollectionUtils.isEmpty(recommendedHotelDTOList)) {
            return null;
        }
        for (RecommendedHotelDTO recommendedHotelDTO : recommendedHotelDTOList) {
            HotelProductIncreaseStrategyRule hotelProductIncreaseStrategyRule = null;
            // 查询酒店-当前日期加幅策略
            HotelProductStrategyDTO hotelProductStrategyDTO = hotelProductStrategyMapper.queryHotelProductStrategyInfo(recommendedHotelDTO.getProductId(), nowDate);
            if (hotelProductStrategyDTO != null) {
                if (hotelProductStrategyDTO.getSelfSalePermissionType() == SALE_CHANNEL_TYPE_DISABLED) {
                    // 自营禁售
                    continue;
                } else if (hotelProductStrategyDTO.getSelfSalePermissionType() == SALE_CHANNEL_TYPE_ALL) {
                    //酒店-线下自营所有-获取加幅规则
                    hotelProductIncreaseStrategyRule = ruleMapper.selectById(hotelProductStrategyDTO.getSelfSalePermissionId());
                } else if (hotelProductStrategyDTO.getSelfSalePermissionType() == SALE_CHANNEL_TYPE_SELECTED) {
                    //酒店-线下自营选中-获取加幅规则
                    QueryWrapper<HotelProductChannelOfflineSelfCustom> offlineSelfQueryWrapper = new QueryWrapper<>();
                    offlineSelfQueryWrapper.lambda().eq(HotelProductChannelOfflineSelfCustom::getRelationId, userId);
                    offlineSelfQueryWrapper.lambda().eq(HotelProductChannelOfflineSelfCustom::getIncreaseStrategyId, hotelProductStrategyDTO.getId());
                    HotelProductChannelOfflineSelfCustom hotelProductChannelOfflineSelfCustom = hotelProductChannelOfflineSelfCustomMapper.selectOne(offlineSelfQueryWrapper);
                    if (hotelProductChannelOfflineSelfCustom != null) {
                        // 酒店-线下自营选中-查询加幅规则
                        QueryWrapper<HotelProductIncreaseStrategyRule> ruleQueryWrapper = new QueryWrapper<>();
                        ruleQueryWrapper.lambda().eq(HotelProductIncreaseStrategyRule::getCustomId, hotelProductChannelOfflineSelfCustom.getId());
                        hotelProductIncreaseStrategyRule = ruleMapper.selectOne(ruleQueryWrapper);
                    } else {
                        SysDepartmentDTO sysDepartmentDTO = sysDepartmentService.queryByUserId(userId);
                        hotelProductChannelOfflineSelfCustom = findParentDepartmentId(sysDepartmentDTO, hotelProductStrategyDTO.getId());
                        if (hotelProductChannelOfflineSelfCustom != null) {
                            // 酒店-线下自营选中-查询加幅规则
                            QueryWrapper<HotelProductIncreaseStrategyRule> ruleQueryWrapper = new QueryWrapper<>();
                            ruleQueryWrapper.lambda().eq(HotelProductIncreaseStrategyRule::getCustomId, hotelProductChannelOfflineSelfCustom.getId());
                            hotelProductIncreaseStrategyRule = ruleMapper.selectOne(ruleQueryWrapper);
                        }
                    }
                }
            }

//            if (hotelProductIncreaseStrategyRule != null) {
//                if(!API.equals(recommendedHotelDTO.getProductSource())){
//                    // 酒店-按照初始化设置查询加幅规则
//                    buildIncreasePrice(recommendedHotelDTO,hotelProductIncreaseStrategyRule.getPriceType(),hotelProductIncreaseStrategyRule.getPrice());
//                }
//            }
        }
        return recommendedHotelDTOList;
    }

    /**
     * 根据部门信息，递归查询加幅策略-线下自营信息
     *
     * @param sysDepartmentDTO   部门信息
     * @param increaseStrategyId 加幅策略id
     * @return 加幅策略-线下自营信息
     */
    private HotelProductChannelOfflineSelfCustom findParentDepartmentId(SysDepartmentDTO sysDepartmentDTO, Long increaseStrategyId) {
        QueryWrapper<HotelProductChannelOfflineSelfCustom> offlineSelfQueryWrapper = new QueryWrapper<>();
        offlineSelfQueryWrapper.eq("relation_id", sysDepartmentDTO.getId());
        offlineSelfQueryWrapper.lambda().eq(HotelProductChannelOfflineSelfCustom::getIncreaseStrategyId, increaseStrategyId);
        HotelProductChannelOfflineSelfCustom hotelProductChannelOfflineSelfCustom = hotelProductChannelOfflineSelfCustomMapper.selectOne(offlineSelfQueryWrapper);
        if (hotelProductChannelOfflineSelfCustom == null && sysDepartmentDTO.getParentId() != null) {
            // 查找上級部門
            SysDepartmentDTO sysDepartmentDTOTemp = sysDepartmentService.queryOne(sysDepartmentDTO.getParentId());
            if (sysDepartmentDTOTemp == null) {
                return null; //没有上级部门，返回null
            }
            hotelProductChannelOfflineSelfCustom = findParentDepartmentId(sysDepartmentDTOTemp, increaseStrategyId);

        }
        return hotelProductChannelOfflineSelfCustom;
    }

    /**
     * 校验产品信息入参
     * @param hotelProductReq
     * @param user
     * @return
     */
    private Result checkProductReq(HotelProductReq hotelProductReq, TokenUser user){
        if(Objects.isNull(user)){
            return Result.failed(SystemError.USER_1000);
        }
        if(Objects.isNull(hotelProductReq)){
            return Result.failed(SystemError.HOTEL_10039);
        }
        return null;
    }

    /**
     * 产品成本日期校验
     * @param hotelProductCostAddReq
     * @return
     */
    private Result<Object> checkCostateResult(List<HotelProductCostAddReq> hotelProductCostAddReq) {
        List<HotelProductCostDateData> hotelProductCostDateReqList = new ArrayList<>();
        // 四种渠道至少有一个在售校验
        for (HotelProductCostAddReq req : hotelProductCostAddReq) {
            hotelProductCostDateReqList.addAll(req.getHotelProductCostDateReqList());
        }
        for (int i = 0; i < hotelProductCostDateReqList.size(); i++) {
            HotelProductCostDateData productCostDateReq = hotelProductCostDateReqList.get(i);
            if (productCostDateReq.getDateBegin().isBefore(LocalDate.now())) {
                // 酒店产品加幅策略保存，开始日期不能小于当前日期校验
                return Result.failed(SystemError.HOTEL_10053);
            }
            if (i == 0 && productCostDateReq.getDateBegin().isAfter(productCostDateReq.getDateEnd())) {
                // 开始日期必须小于结束日期校验
                return Result.failed(SystemError.HOTEL_10064);
            }
            for (int j = 0; j < hotelProductCostDateReqList.size(); j++) {
                HotelProductCostDateData costDateReqTemp = hotelProductCostDateReqList.get(j);
                if (i >= j) { // 自身和已经校验过的跳过日期校验
                    continue;
                }
                if (i == 0 && costDateReqTemp.getDateBegin().isAfter(costDateReqTemp.getDateEnd())) {
                    // 开始日期必须小于结束日期校验
                    return Result.failed(SystemError.HOTEL_10064);
                }
                if (DateUtil.match(productCostDateReq.getDateBegin(), productCostDateReq.getDateEnd(), costDateReqTemp.getDateBegin(), costDateReqTemp.getDateEnd())) {
                    // 当前日期与其他日期区域重叠校验
                    return Result.failed(SystemError.HOTEL_10060);
                }
            }
        }
        return null;
    }

    /**
     * 新增-编辑提交审批
     * @param id
     * @param user
     */
    @Override
    public Result submit(Long id, TokenUser user) {
        HotelProduct hotelProduct = hotelProductMapper.selectById(id);
        if(Objects.isNull(hotelProduct)){
            return Result.failed(SystemError.HOTEL_10038);
        }
        //非待提交状态不能进行审批
        if(!ApproveCode.UN_COMMIT.getCode().equals(hotelProduct.getApprovalStatus())){
            return Result.failed(SystemError.HOTEL_10057);
        }
        hotelProduct.setApprovalStatus(ApproveCode.APPROVING.getCode());
        hotelProduct.setModifiedId(user.getId());
        hotelProduct.setGmtModified(LocalDateTime.now());
        hotelProductMapper.updateById(hotelProduct);
        return Result.success();
    }

    /**
     * 修改审核通过酒店产品
     * @param hotelProductReq
     * @param user
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result updateApprovedHotelProduct(HotelProductReq hotelProductReq, TokenUser user) {

        Result checkResult = checkProductReq(hotelProductReq,user);
        if(!Objects.isNull(checkResult)){
            return checkResult;
        }

        Result result = checkCostateResult(hotelProductReq.getHotelProductCostDataReqs());
        if(!Objects.isNull(result)){
            return result;
        }
        List<Long> hotelProductIdList = new ArrayList<>();


        //更新酒店产品信息
        HotelProduct hotelProduct = hotelProductMapper.selectById(hotelProductReq.getId());
        if(Objects.isNull(hotelProduct)){
            return Result.failed(SystemError.HOTEL_10038);
        }
        if(!ApproveCode.APPROVE_PASS.getCode().equals(hotelProduct.getApprovalStatus())){
            return Result.failed(SystemError.HOTEL_10054);
        }

        if(IsValidCode.VALID.getCode().equals(hotelProduct.getSaleStatus())){
            return Result.failed(SystemError.TRAIN_PRODUCT_9029);
        }
        hotelProductIdList.add(hotelProduct.getId());
        BeanUtils.copyProperties(hotelProductReq,hotelProduct);
        hotelProduct.setModifiedId(user.getId());
        hotelProduct.setGmtModified(LocalDateTime.now());
        hotelProductMapper.updateById(hotelProduct);

        //查询酒店产品成本信息
        List<HotelProductCost> hotelProductCostLists = hotelProductCostMapper.selectList(new QueryWrapper<HotelProductCost>().lambda().eq(HotelProductCost::getHotelProductId, hotelProduct.getId()));

        //更新酒店产品成本相关信息- 先删后插入
        for(HotelProductCost hotelProductCost : hotelProductCostLists){
            hotelProductCostDateMapper.delete(new QueryWrapper<HotelProductCostDate>().lambda().eq(HotelProductCostDate::getCostId, hotelProductCost.getId()));
        }
        hotelProductCostMapper.delete(new QueryWrapper<HotelProductCost>().lambda().eq(HotelProductCost::getHotelProductId, hotelProduct.getId()));

        //保存酒店产品成本信息
        List<HotelProductCostAddReq> hotelProductCostReqList = hotelProductReq.getHotelProductCostDataReqs();
        for(HotelProductCostAddReq hotelProductCostReq : hotelProductCostReqList){
            //保存酒店产品成本
            HotelProductCost hotelProductCost = new HotelProductCost();
            BeanUtils.copyProperties(hotelProductCostReq,hotelProductCost);
            Long costId = SnowflakeIdWorker.nextId();
            hotelProductCost.setId(costId);
            hotelProductCost.setHotelProductId(hotelProduct.getId());
            hotelProductCostMapper.insert(hotelProductCost);

            //保存酒店产品成本日期
            List<HotelProductCostDateData> hotelProductCostDateReqList = hotelProductCostReq.getHotelProductCostDateReqList();
            for(HotelProductCostDateData hotelProductCostDateReq : hotelProductCostDateReqList){
                HotelProductCostDate hotelProductCostDate = new HotelProductCostDate();
                BeanUtils.copyProperties(hotelProductCostDateReq,hotelProductCostDate);
                hotelProductCostDate.setId(SnowflakeIdWorker.nextId());
                hotelProductCostDate.setCostId(costId);
                hotelProductCostDateMapper.insert(hotelProductCostDate);
            }
        }
        return Result.success(hotelProductIdList);
    }

    /**
     * 修改审核不通过酒店产品
     * @param hotelProductReq
     * @param user
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result updateUnapprovedHotelProduct(HotelProductReq hotelProductReq, TokenUser user) {

        Result checkResult = checkProductReq(hotelProductReq,user);
        if(!Objects.isNull(checkResult)){
            return checkResult;
        }

        Result result = checkCostateResult(hotelProductReq.getHotelProductCostDataReqs());
        if(!Objects.isNull(result)){
            return result;
        }

        HotelProduct hotelProduct = hotelProductMapper.selectById(hotelProductReq.getId());
        if(Objects.isNull(hotelProduct)){
            return Result.failed(SystemError.HOTEL_10038);
        }

        if(!ApproveCode.APPROVE_REJECT.getCode().equals(hotelProduct.getApprovalStatus())
                && !ApproveCode.UN_COMMIT.getCode().equals(hotelProduct.getApprovalStatus())){
            return Result.failed(SystemError.HOTEL_10015);
        }
        if(IsValidCode.VALID.getCode().equals(hotelProduct.getSaleStatus())){
            return Result.failed(SystemError.TRAIN_PRODUCT_9029);
        }

        //审核不通过修改 等同于新增(必须先删后新增)
        hotelProductMapper.deleteById(hotelProductReq.getId());
        List<HotelProductCost> hotelProductCostLists = hotelProductCostMapper.selectList(new QueryWrapper<HotelProductCost>().lambda().eq(HotelProductCost::getHotelProductId, hotelProductReq.getId()));

        for(HotelProductCost hotelProductCost : hotelProductCostLists){
            hotelProductCostDateMapper.delete(new QueryWrapper<HotelProductCostDate>().lambda().eq(HotelProductCostDate::getCostId, hotelProductCost.getId()));
        }
        hotelProductCostMapper.delete(new QueryWrapper<HotelProductCost>().lambda().eq(HotelProductCost::getHotelProductId, hotelProductReq.getId()));
        //审核不通过的产品 调用新增方法
        return this.addProductInfo(hotelProductReq,user);
    }

    /**
     * 新增酒店产品
     * @param hotelProductReq
     */
    private Result addProductInfo(HotelProductReq hotelProductReq,TokenUser user){
            //保存酒店产品信息
            HotelProduct hotelProduct = EntityUtil.copy(hotelProductReq, HotelProduct.class);
            Long hotelProductId = SnowflakeIdWorker.nextId();
            hotelProduct.setProductCode(buildOrderNumber(user.getId(), LocalDateTime.now()));
            hotelProduct.setId(hotelProductId);
            //如果页面没有填写负责人,则默认当前账号
            if(StringUtils.isEmpty(hotelProduct.getChargeId())){
                hotelProduct.setChargeId(user.getId());
                hotelProduct.setChargeUser(user.getUsername());
            }
            hotelProduct.setCreateId(user.getId());
            hotelProduct.setGmtCreate(LocalDateTime.now());
            hotelProduct.setIsDeleted(IsDeletedCode.NO.getCode());
            hotelProduct.setSourceType(ProductType.MANUAL_ENTRY.getCode());
            hotelProductMapper.insert(hotelProduct);

            //保存酒店产品成本信息
            List<HotelProductCostAddReq> hotelProductCostReqList = hotelProductReq.getHotelProductCostDataReqs();
            for(HotelProductCostAddReq hotelProductCostReq : hotelProductCostReqList){
                //保存酒店产品成本
                HotelProductCost hotelProductCost = EntityUtil.copy(hotelProductCostReq, HotelProductCost.class);
                Long costId = SnowflakeIdWorker.nextId();
                hotelProductCost.setId(costId);
                hotelProductCost.setHotelProductId(hotelProductId);
                hotelProductCostMapper.insert(hotelProductCost);

                //保存酒店产品成本日期
                List<HotelProductCostDateData> hotelProductCostDateReqList = hotelProductCostReq.getHotelProductCostDateReqList();
                for(HotelProductCostDateData hotelProductCostDateReq : hotelProductCostDateReqList){
                    HotelProductCostDate hotelProductCostDate = EntityUtil.copy(hotelProductCostDateReq, HotelProductCostDate.class);
                    hotelProductCostDate.setId(SnowflakeIdWorker.nextId());
                    hotelProductCostDate.setCostId(costId);
                    hotelProductCostDateMapper.insert(hotelProductCostDate);
                }
            }
        return Result.success(hotelProduct);
    }

    /**
     * 生成酒店产品编码=PB+员工编号+月日4位+时分4位+3位随机数字
     *
     * @param userId
     * @return
     */
    private String buildOrderNumber(Long userId, LocalDateTime nowLocalDateTime) {
        UserDTO userDTO = sysUserService.loadUserByParam(userId, 1);
        String employeeNumber = userDTO.getEmployeeNumber();
        String monthCode = org.apache.commons.lang3.StringUtils.leftPad(String.valueOf(nowLocalDateTime.getMonthValue()), 2, "0");
        String dayCode = org.apache.commons.lang3.StringUtils.leftPad(String.valueOf(nowLocalDateTime.getDayOfMonth()), 2, "0");
        String hourCode = org.apache.commons.lang3.StringUtils.leftPad(String.valueOf(nowLocalDateTime.getHour()), 2, "0");
        String minuteCode = org.apache.commons.lang3.StringUtils.leftPad(String.valueOf(nowLocalDateTime.getMinute()), 2, "0");
        String randomNumber = String.valueOf((int) ((Math.random() * 9 + 1) * 100));
        StringBuilder orderNumberSb = new StringBuilder();
        orderNumberSb.append("PB").append(employeeNumber).append(monthCode).append(dayCode).append(hourCode).append(minuteCode).append(randomNumber);
        return orderNumberSb.toString();
    }

    /**
     * 预订中心-酒店预订详情
     * @param hotelId
     */
    @Override
    public HotelReservestionStockAndPriceDTO bookingHotel(Long hotelId, TokenUser user){
        HotelReservestionStockAndPriceDTO hotelReservestionStockAndPriceDTO = new HotelReservestionStockAndPriceDTO();
        //先获取酒店信息
            QueryWrapper<Hotel> queryWrapperHotel = new QueryWrapper<>();
        queryWrapperHotel.lambda().eq(Hotel::getId,hotelId);
        queryWrapperHotel.lambda().eq(Hotel::getIsDeleted,IsDeletedCode.NO.getCode());
        Hotel hotel = hotelMapper.selectOne(queryWrapperHotel);
        if(hotel!=null){
            //组装酒店基本信息
            hotelReservestionStockAndPriceDTO.setAreaName(hotel.getAreaName());
            hotelReservestionStockAndPriceDTO.setHotelName(hotel.getName());
            hotelReservestionStockAndPriceDTO.setEnHotelName(hotel.getEnName());
            hotelReservestionStockAndPriceDTO.setHotelTypeName(hotel.getHotelTypeName());
            hotelReservestionStockAndPriceDTO.setStarLevel(hotel.getStarLevel());
            hotelReservestionStockAndPriceDTO.setLocation(hotel.getLocation());
            hotelReservestionStockAndPriceDTO.setPostalCode(hotel.getPostalCode());
            hotelReservestionStockAndPriceDTO.setTelephone(hotel.getTelephone());
            hotelReservestionStockAndPriceDTO.setLocToDistrictDistance(hotel.getLocToDistrictDistance());
            hotelReservestionStockAndPriceDTO.setBusinessDistrictName(hotel.getBusinessDistrictName());
            hotelReservestionStockAndPriceDTO.setId(hotel.getId());
            hotelReservestionStockAndPriceDTO.setShowPhotoJson(hotel.getShowPhotoJson());
            hotelReservestionStockAndPriceDTO.setCoverMap(hotel.getCoverMap());
            hotelReservestionStockAndPriceDTO.setHotelContent(hotel.getHotelContent());
            hotelReservestionStockAndPriceDTO.setLatitude(hotel.getLatitude());
            hotelReservestionStockAndPriceDTO.setLongitude(hotel.getLongitude());
            hotelReservestionStockAndPriceDTO.setOpeningTime(hotel.getOpeningTime());
            hotelReservestionStockAndPriceDTO.setFinalRenovationTime(hotel.getFinalRenovationTime());
            hotelReservestionStockAndPriceDTO.setHotelPolicy(hotel.getHotelPolicy());
            hotelReservestionStockAndPriceDTO.setAreaName(hotel.getAreaName());
            //查询酒店设施信息
            QueryWrapper<HotelFacilities> queryWrapperHotelFacilities = new QueryWrapper<>();
            queryWrapperHotelFacilities.lambda().eq(HotelFacilities::getHotelId,hotelId);
            queryWrapperHotelFacilities.lambda().eq(HotelFacilities::getIsDeleted,IsDeletedCode.NO.getCode());
            List<HotelFacilities> hotelFacilitiesLists = hotelFacilitiesMapper.selectList(queryWrapperHotelFacilities);
            //组装酒店设施信息
            List<HotelFacilitiesDTO> hotelFacilitiesDTOList = new ArrayList<HotelFacilitiesDTO>();
            if(CollectionUtil.isNotEmpty(hotelFacilitiesLists)){
                for (int i = 0; i < hotelFacilitiesLists.size(); i++) {
                    HotelFacilitiesDTO hotelFacilitiesDTO = EntityUtil.copy(hotelFacilitiesLists.get(i), HotelFacilitiesDTO.class);
                    hotelFacilitiesDTOList.add(hotelFacilitiesDTO);
                }
            }
            hotelReservestionStockAndPriceDTO.setHotelFacilitiesDTOList(hotelFacilitiesDTOList);
            //查询房型列表
            List<HotelReservestionProductListDetailDTO> hotelReservestionProductListDetailDTO = hotelProductMapper.queryHotelReservestionProductListDetailDTO();
            /**此处还需要查询每一个产品的加幅以及服务费价格*/
            hotelReservestionStockAndPriceDTO.setHotelReservestionProductListDetailDTO(hotelReservestionProductListDetailDTO);
        }else{
            Result.failed(SystemError.HOTEL_NULL_10012);
        }
            return hotelReservestionStockAndPriceDTO;
        }

    /**
     * 获取酒店产品价格（加幅价格）
     * @param getHotelPriceReq
     */
    @Override
    public Result getHotelProductPrice(GetHotelPriceReq getHotelPriceReq){
        if(getHotelPriceReq.getProductId()==null){
            Result.failed(SystemError.HOTEL_10069);
        }
        if(getHotelPriceReq.getPriceDate()==null){
            Result.failed(SystemError.HOTEL_10070);
        }
        //获取产品成本价格，库存
        QueryWrapper<HotelProductCost> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(HotelProductCost::getHotelProductId,getHotelPriceReq.getProductId());
        List<HotelProductCost> hotelProductCostList = hotelProductCostMapper.selectList(queryWrapper);
        if(CollectionUtil.isNotEmpty(hotelProductCostList)){

        }else{
            Result.failed(SystemError.HOTEL_10071);
        }

        return Result.success();
    }


    /**
     * 判断时间是否在时间段内
     * */
    public  boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        }else if(nowTime.compareTo(beginTime)==0 || nowTime.compareTo(endTime) == 0 ){
            return true;
        }else {
            return false;
        }
    }


    @Override
    public HotelPriceRemainderDTO selectSelfPriceRemainderAndLock(HotelIncreaseStrategyPriceQueryReq priceQueryReq) {
        HotelPriceRemainderDTO airportExpressPriceRemainderDTO = new HotelPriceRemainderDTO();
        LocalDate nowDate = LocalDate.now();
        Integer remainderNumber = null;
        HotelProduct hotelProduct = hotelProductMapper.selectById(priceQueryReq.getHotelProductId());
        HotelProductStrategy airportExpressIncreaseStrategy = hotelProductStrategyMapper.selectByHotelProductIdNowDate(priceQueryReq.getHotelProductId(), nowDate.toString());
        // 获取加幅策略规则
        HotelProductIncreaseStrategyRule aeIncreaseStrategyRule = getHotelProductIncreaseStrategyRule(priceQueryReq, airportExpressIncreaseStrategy);
        // 机场快线-加幅规则失效后，按照初始化设置查询加幅规则
        if (aeIncreaseStrategyRule != null) {
            if (aeIncreaseStrategyRule.getSaleableType() == OrderHotelProductConstants.SALE_TYPE_LIMIT) {
                // 票数有限制，计算余票数量
                int saleableNumber = aeIncreaseStrategyRule.getSaleableNumber() == null ? 0 : aeIncreaseStrategyRule.getSaleableNumber();
                int soldNumber = aeIncreaseStrategyRule.getSoldNumber() == null ? 0 : aeIncreaseStrategyRule.getSoldNumber();
                remainderNumber = saleableNumber - soldNumber;
                if (priceQueryReq.getTouristNumber() > remainderNumber) {
                    // 旅客人数大于余票数量
                    throw new BusinessException(SystemError.HOTEL_10073);
                }
                // 锁定票数 AtomicIncreaseSoldNumber
                HotelProductIncreaseStrategyRule updateStrategyRule = new HotelProductIncreaseStrategyRule();
                updateStrategyRule.setId(aeIncreaseStrategyRule.getId());
                updateStrategyRule.setSoldNumber(soldNumber + priceQueryReq.getTouristNumber());
                hotelProductIncreaseStrategyRuleMapper.updateById(updateStrategyRule);
            }
        }
        HashMap<Integer, BigDecimal> priceMap = buildIncreasePrice(hotelProduct, aeIncreaseStrategyRule);
        airportExpressPriceRemainderDTO.setPrice(hotelProduct.getMinPrice());
        airportExpressPriceRemainderDTO.setPrice(priceMap.get(0));
//        airportExpressPriceRemainderDTO.setChildrenPrice(priceMap.get(1));
        airportExpressPriceRemainderDTO.setSaleableType(aeIncreaseStrategyRule.getSaleableType());
        airportExpressPriceRemainderDTO.setRemainderNumber(remainderNumber);
        return airportExpressPriceRemainderDTO;
    }

    /**
     * 获取机场快线加幅规则，自营规则或代理规则
     *
     * @param priceQueryReq
     * @param hotelProductStrategy
     * @return
     */
    private HotelProductIncreaseStrategyRule getHotelProductIncreaseStrategyRule(HotelIncreaseStrategyPriceQueryReq priceQueryReq, HotelProductStrategy hotelProductStrategy) {
        HotelProductIncreaseStrategyRule aeIncreaseStrategyRule = null;
        if (hotelProductStrategy != null) {
            if (priceQueryReq.getAgentId() == null) {
                if (hotelProductStrategy.getSelfSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_DISABLED) {
                    // 代理禁售
                    throw new BusinessException(SystemError.HOTEL_10072);
                } else if (hotelProductStrategy.getSelfSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_ALL) {
                    //当前机场快线-线下自营所有-获取加幅规则
                    aeIncreaseStrategyRule = hotelProductIncreaseStrategyRuleMapper.selectById(hotelProductStrategy.getSelfSalePermissionId());

                } else if (hotelProductStrategy.getSelfSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_SELECTED) {
                    //当前机场快线-线下自营选中-获取加幅规则
                    QueryWrapper<HotelProductChannelOfflineSelfCustom> offlineSelfQueryWrapper = new QueryWrapper<>();
                    offlineSelfQueryWrapper.lambda().eq(HotelProductChannelOfflineSelfCustom::getRelationId, priceQueryReq.getUserId());
                    offlineSelfQueryWrapper.lambda().eq(HotelProductChannelOfflineSelfCustom::getIncreaseStrategyId, hotelProductStrategy.getId());
                    HotelProductChannelOfflineSelfCustom hotelProductChannelOfflineSelfCustom = hotelProductChannelOfflineSelfCustomMapper.selectOne(offlineSelfQueryWrapper);
                    if (hotelProductChannelOfflineSelfCustom != null) {
                        // 当前机场快线-线下自营选中-查询加幅规则
                        QueryWrapper<HotelProductIncreaseStrategyRule> ruleQueryWrapper = new QueryWrapper<>();
                        ruleQueryWrapper.lambda().eq(HotelProductIncreaseStrategyRule::getCustomId, hotelProductChannelOfflineSelfCustom.getId());
                        aeIncreaseStrategyRule = hotelProductIncreaseStrategyRuleMapper.selectOne(ruleQueryWrapper);

                    } else {
                        SysDepartmentDTO sysDepartmentDTO = sysDepartmentService.queryByUserId(priceQueryReq.getUserId());
                        hotelProductChannelOfflineSelfCustom = findParentDepartmentId(sysDepartmentDTO, hotelProductStrategy.getId());
                        if (hotelProductChannelOfflineSelfCustom != null) {
                            // 当前机场快线-线下自营选中-查询加幅规则
                            QueryWrapper<HotelProductIncreaseStrategyRule> ruleQueryWrapper = new QueryWrapper<>();
                            ruleQueryWrapper.lambda().eq(HotelProductIncreaseStrategyRule::getCustomId, hotelProductChannelOfflineSelfCustom.getId());
                            aeIncreaseStrategyRule = hotelProductIncreaseStrategyRuleMapper.selectOne(ruleQueryWrapper);
                        }
                    }
                }
            } else if (priceQueryReq.getAgentId() != null) {
                // 代理禁售
                if (hotelProductStrategy.getAgentSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_DISABLED) {
                    return null;
                } else if (hotelProductStrategy.getAgentSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_ALL) {
                    // 当前机场快线-线下自营所有-获取加幅规则
                    aeIncreaseStrategyRule = hotelProductIncreaseStrategyRuleMapper.selectById(hotelProductStrategy.getAgentSalePermissionId());
                } else if (hotelProductStrategy.getAgentSalePermissionType() == OrderHotelProductConstants.SALE_CHANNEL_TYPE_SELECTED) {
                    //当前机场快线-线下代理选中-获取代理加幅规则列表
                    QueryWrapper<HotelProductChannelOfflineAgentCustom> offlineAgentQueryWrapper = new QueryWrapper<>();
                    offlineAgentQueryWrapper.lambda().eq(HotelProductChannelOfflineAgentCustom::getIncreaseStrategyId, hotelProductStrategy.getId());
                    offlineAgentQueryWrapper.lambda().eq(HotelProductChannelOfflineAgentCustom::getAgentId, priceQueryReq.getAgentId());
                    HotelProductChannelOfflineAgentCustom airportExpressChannelOfflineAgentCustom = hotelProductChannelOfflineAgentCustomMapper.selectOne(offlineAgentQueryWrapper);
                    if (airportExpressChannelOfflineAgentCustom != null) {
                        // 当前机场快线-线下代理选中-查询加幅规则
                        QueryWrapper<HotelProductIncreaseStrategyRule> ruleQueryWrapper = new QueryWrapper<>();
                        ruleQueryWrapper.lambda().eq(HotelProductIncreaseStrategyRule::getCustomId, airportExpressChannelOfflineAgentCustom.getId());
                        aeIncreaseStrategyRule = hotelProductIncreaseStrategyRuleMapper.selectOne(ruleQueryWrapper);

                    }
                }
            }
        }
        return aeIncreaseStrategyRule;
    }

    /**
     * 计算加幅价格
     *
     * @param hotelProduct                     目标机场快线
     * @param hotelProductIncreaseStrategyRule 加幅规则
     */
    public HashMap buildIncreasePrice(HotelProduct hotelProduct, HotelProductIncreaseStrategyRule hotelProductIncreaseStrategyRule) {
        HashMap<Integer, BigDecimal> integerBigDecimalHashMap = new HashMap<>(2);
            // 数值加幅
            if (hotelProductIncreaseStrategyRule.getPriceType() == IncreasePriceType.NUMERIC.getCode()) {
                BigDecimal adultOneWayPrice = hotelProduct.getMinPrice().add(hotelProductIncreaseStrategyRule.getPrice());
                integerBigDecimalHashMap.put(0, adultOneWayPrice);
            }
            // 百分比加幅
            if (hotelProductIncreaseStrategyRule.getPriceType() == IncreasePriceType.PERCENT.getCode()) {
                BigDecimal per = hotelProductIncreaseStrategyRule.getPrice().divide(new BigDecimal("100")).add(BigDecimal.ONE);
                BigDecimal adultOneWayPrice = hotelProduct.getMinPrice().multiply(per);
                integerBigDecimalHashMap.put(0, adultOneWayPrice);
            }
        return integerBigDecimalHashMap;
    }

    @Override
    public HotelProductInfoDTO selectInfo(Long id) {
        HotelProduct hotelProduct = hotelProductMapper.selectById(id);
        if (hotelProduct == null) {
            // 无数据
            throw new BusinessException(SystemError.HOTEL_10065);
        }
        HotelProductInfoDTO hotelProductInfoDTO = EntityUtil.copy(hotelProduct,HotelProductInfoDTO.class);
        Integer agentSaleType = hotelProductStrategyMapper.selectAgentSaleTypeByIdDate(id, LocalDate.now());
        hotelProductInfoDTO.setAgentSaleType(agentSaleType);
        // 查询退改手续费
        /*BigDecimal cancellationCharge = getCancellationCharge(hotelProduct);
        hotelProductInfoDTO.setRefundCharge(cancellationCharge);*/
        return hotelProductInfoDTO;
    }

    @Override
    public HotelProductInfoDTO selectById(Long id) {
        HotelProduct hotelProduct = hotelProductMapper.selectById(id);
        if (hotelProduct == null || hotelProduct.getIsDeleted() == 1) {
            // 无数据
            return null;
        }
        HotelProductInfoDTO hotelProductInfoDTO = EntityUtil.copy(hotelProduct,HotelProductInfoDTO.class);
        Integer agentSaleType = hotelProductStrategyMapper.selectAgentSaleTypeByIdDate(id, LocalDate.now());
        hotelProductInfoDTO.setAgentSaleType(agentSaleType);
        // 查询退改手续费
        BigDecimal cancellationCharge = getCancellationCharge(hotelProduct);
        hotelProductInfoDTO.setRefundCharge(cancellationCharge);
        return hotelProductInfoDTO;
    }

    @Override
    public Result<HotelProductUnitPriceDTO> queryUnitPrice(HotelProductUnitPriceReq req, Long userId) {
        // 获取当前用户所有上级部门id,并把自己用户id加入list中,目的是查询整个关联字段
        List<Long> deptIds = new ArrayList<>();
        deptIds.add(userId);
        deptIds.addAll(sysDepartmentService.queryIdsByUserId(userId));

        List<LocalDate> dates = DateUtil.getMiddleDate(req.getCheckInDate(), req.getCheckOutDate());
        // 如果时间大于1天,则删除最后一天的日期,因为最后一天是离店时间不算入住
        if (dates.size() > 1) {
            dates.remove(dates.size() - 1);
        }
        HotelProductUnitPriceDTO dto = hotelProductMapper.queryProductUnitPrice(deptIds, req, dates);
        if (null != dto) {
            dto.setUnitPrice(dto.getUnitPrice() == null ? new BigDecimal(0.00) : dto.getUnitPrice());
            dto.setTaxation(dto.getTaxation() == null ? new BigDecimal(0.00) : dto.getTaxation());
        }
        return Result.success(dto);
    }

    @Override
    public Long approvalStart(long productId, long userId) {
        HotelProduct hotelProduct = hotelProductMapper.selectOne(Wrappers.<HotelProduct>lambdaQuery()
                .eq(HotelProduct::getId, productId)
                .eq(HotelProduct::getIsDeleted,IsDeletedCode.NO.getCode()));
        if (hotelProduct == null) {
            throw new BusinessException(SystemError.HOTEL_10014);
        }
        // 保存并发起审批
        Result<ApprovalStartDTO> startDTOResult = sysApprovalService.start(SystemBusinessType.HOTEL.getCode(), SysApprovalType.ADD_HOTEL.getCode(), hotelProduct.getId(), userId, null, null);
        if (!startDTOResult.isSuccess()) {
            SystemError systemError = SystemError.getDefined(startDTOResult.getCode());
            throw new BusinessException(systemError);
        }
        hotelProduct.setApprovalStatus(ApprovalStatus.REVIEWING.getCode());
        hotelProduct.setGmtModified(LocalDateTime.now());
        hotelProductMapper.updateById(hotelProduct);

        return hotelProduct.getId();
    }

    @Override
    public Long approvalCheck(long approvalId, long businessId, long userId, int status, String comments) {
        Result<ApprovalCheckDTO> checkDTOResult = sysApprovalService.check(approvalId, userId, status, comments);
        if (!checkDTOResult.isSuccess()) {
            SystemError systemError = SystemError.getDefined(checkDTOResult.getCode());
            throw new BusinessException(systemError);
        }

        log.info("整个审批流程是否完成[{}]", checkDTOResult.getData().getIsFinish());

        if (ApprovalStatus.REVIEW_YES.getCode().equals(status) && !checkDTOResult.getData().getIsFinish()) {
            // 审批通过但未完成则不操作业务数据
            return approvalId;
        }

        HotelProduct hotelProduct = hotelProductMapper.selectOne(Wrappers.<HotelProduct>lambdaQuery()
                .eq(HotelProduct::getId, businessId)
                .eq(HotelProduct::getIsDeleted,IsDeletedCode.NO.getCode()));

        int approvalStatus = status;
        if (status == ApprovalStatus.REVIEW_NO.getCode()) {
            approvalStatus = ApprovalStatus.WAIT_SUBMIT.getCode();
        }
        hotelProduct.setApprovalStatus(approvalStatus);
        // 销售状态为有效
        hotelProduct.setSaleStatus(1);
        hotelProduct.setGmtModified(LocalDateTime.now());
        hotelProductMapper.updateById(hotelProduct);

        return businessId;
    }

    @Override
    public Result<HotelStockDTO> findHotelSalePriceInfoHandle(int strategyType, long productId, LocalDate checkInDate, LocalDate checkOutDate, int roomNum, long relId) {
        if (strategyType == 0 || productId == 0 || relId == 0) {
            return Result.failed(SystemError.SYS_409);
        }
        if (roomNum == 0) {
            roomNum = 1;
        }
        List<Long> deptIds = new ArrayList<>();
        if (strategyType == 1 || strategyType == 2) {
            // 获取当前用户所有上级部门id,并把自己用户id加入list中,目的是查询整个关联字段
            deptIds.add(relId);
            deptIds.addAll(sysDepartmentService.queryIdsByUserId(relId));
        }

        List<LocalDate> dates = DateUtil.getMiddleDate(checkInDate, checkOutDate);
        int dateType = 2;
        // 如果时间大于1天,则删除最后一天的日期,因为最后一天是离店时间不算入住
        if (dates.size() > 1) {
            dates.remove(dates.size() - 1);
            dateType = 1;
        }
        if (dates.size() == 1) {
            dateType = 2;
        }
        HotelStockDTO hotelStock = hotelProductMapper.querySeasonProductsByProductId(strategyType, productId, dates, checkInDate, checkOutDate, roomNum, relId, deptIds, dateType);
        if (null == hotelStock) {
            return Result.failed(SystemError.HOTEL_10014);
        }
        hotelStock.setPrice(hotelStock.getPrice() == null ? BigDecimal.ZERO : hotelStock.getPrice().setScale(0, BigDecimal.ROUND_UP));
        hotelStock.setStock(hotelStock.getStock() == null ? 0 : hotelStock.getStock());
        // int days = DateUtil.daysBetween(checkInDate, checkOutDate);
        // 如果天数是0则默认改成1,防止天数为0时价格被变成0
        // days = days == 0 ? 1 : days;
        // 提交订单页中酒店价格 = 单价 * 天数 * 房间数
        // hotelStock.setPrice(hotelStock.getPrice() == null ? BigDecimal.ZERO : hotelStock.getPrice().multiply(new BigDecimal(days)).multiply(new BigDecimal(roomNum)).setScale(0, BigDecimal.ROUND_UP));

        return Result.success(hotelStock);
    }

    /**
     *
     * @param hotelProduct
     * @return
     */
    private BigDecimal getCancellationCharge(HotelProduct hotelProduct) {
        if (Arrays.asList(1, 2).contains(hotelProduct.getRefundChargeType())) {
            // 产品设置-退改手续费
            if (hotelProduct.getRefundChargeType() == ServiceChargeType.PERCENTAGE.getCode()) {
                BigDecimal percentage = hotelProduct.getRefundCharge().divide(new BigDecimal("100"));
                return hotelProduct.getMinPrice().multiply(percentage);
            } else if (hotelProduct.getRefundChargeType() == ServiceChargeType.FIXED.getCode()) {
                return hotelProduct.getRefundCharge();
            }
        } else {
            // API初始化设置-退改手续费
            HotelInitializationSettings hotelInitializationSettings = hotelInitializationSettingsMapper.selectAll();
            if (hotelInitializationSettings.getServiceChargeType() == ServiceChargeType.PERCENTAGE.getCode()) {
                BigDecimal percentage = hotelInitializationSettings.getServiceCharge().divide(new BigDecimal("100"));
                return hotelProduct.getMinPrice().multiply(percentage);
            } else if (hotelInitializationSettings.getServiceChargeType() == ServiceChargeType.FIXED.getCode()) {
                return hotelInitializationSettings.getServiceCharge();
            }
        }
        return null;
    }
}
